/* ****************************************************************************
 *
 * Copyright (c) Microsoft Corporation. 
 *
 * This source code is subject to terms and conditions of the Microsoft Public License. A 
 * copy of the license can be found in the License.html file at the root of this distribution. If 
 * you cannot locate the  Microsoft Public License, please send an email to 
 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
 * PARTICULAR PURPOSE.
 * ***************************************************************************/


#include "stdafx.h"
#include <pgl/core/PGLMap.h>

#include <pgl/core/PGLMapPropPage.h>
#include <pgl/core/PGLRegion.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

PGL_IMPLEMENT_DYNCREATE(CPGLMap, CPGLObject);

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

//! Save settings
void CPGLMap::SerializeXML(CPGLArchive& ar)
{
	static const TCHAR szTag[] = _T("CPGLMap");
	markup::CMarkupArchive& xml = *((markup::CMarkupArchive*)ar.GetMarkup());
	if(ar.IsStoring())
	{
		xml.AddChildElem(szTag);
		xml.AddChildAttrib(_T("Name"),GetName());
		xml.IntoElem();

			/////////////////////////////////////////////////////////
			// Adding base class
			CPGLObject::SerializeXML(ar);

			xml.AddChildElemEx(_T("ShowWireFrame"),m_bShowWireFrame);
		xml.OutOfElem();
	}
	else
	{
		if  (!xml.FindChildElem(szTag))
				return;

		xml.IntoElem();

			/////////////////////////////////////////////////////////
			// Adding base class
			CPGLObject::SerializeXML(ar);

			xml.FindGetChildData(_T("ShowWireFrame"),m_bShowWireFrame);

		xml.OutOfElem();

		PostUpdateExtent();
	}
}

#ifdef _DEBUG
void CPGLMap::Dump( CDumpContext& dc ) const
{
    // call base class function first
    CPGLObject::Dump( dc );

    // now do the stuff for our specific class
	dc << _T("CPGLMap ID ") << GetID() << "\n";

}
void CPGLMap::AssertValid() const
{
    // call inherited AssertValid first
    CPGLObject::AssertValid();

} 
#endif

CPGLMap::CPGLMap()
: CPGLObject(), m_pLattice(NULL), m_bShowWireFrame(true)
{

}

CPGLMap& CPGLMap::operator = (const CPGLMap& l)
{
	// prevent self-assignement
	if (&l != this)
	{
		// invoke CPGLObject copy assignement operator
		this->CPGLObject::operator =(l);

		m_bShowWireFrame = l.m_bShowWireFrame;
	}
	return *this;
}

void CPGLMap::AddContextMenuItems(CMenu* pMenu)
{
	// call base class
	CPGLObject::AddContextMenuItems(pMenu);	
}

void CPGLMap::AddPropertyPage(CPropertySheet *pPropSheet)
{
	// call own functions
	CPGLMapPropPage* propPage=new CPGLMapPropPage(this);
	pPropSheet->AddPage(propPage);

	// first call base class function
	CPGLObject::AddPropertyPage(pPropSheet);
}

void CPGLMap::PlotGfx(gfxinterface::CGfxInterface& gfx)
{
	// calling base class plot
	CPGLObject::PlotGfx(gfx);
	
	gfx.AddComment(_T("--- CPGLMap ID ---"));
}

void CPGLMap::GetUnionExtent(gfxinterface::CGfxInterface& gfx, CPGLRectD& rExtent)
{
	if (NeedUpdateExtent())
		UpdateExtent(gfx);

	GetExtent().SetUnion(rExtent);

	rExtent.xValid=true;
	rExtent.yValid=true;
}

void CPGLMap::UpdateExtent(gfxinterface::CGfxInterface& gfx)
{
	CPGLRectD rExtent;

	if (m_pLattice)
	{
		contour::TLattice<float>::Rect r;
		m_pLattice->GetBoundingBox(r);
		rExtent.left=r.left;
		rExtent.right=r.right;
		rExtent.bottom=r.bottom;
		rExtent.top=r.top;
	}
	else
	{
		rExtent=CPGLRectD::GetNormBox();
	}

	SetExtent(rExtent);
}

void CPGLMap::SetLattice( contour::TLattice<float>* pLattice, bool bDeleteLattice)
{
	if (m_pLattice && m_bDeleteLattice)
	{
		delete m_pLattice;
	}

	m_bDeleteLattice = bDeleteLattice;
	m_pLattice=pLattice;
}
